--[[
游戏使用一副除去大小王的扑克牌，共4个花色52张牌。
牌靴规则：1.八副牌416张;2.靴头7张(不要的);
3.每场7张，第一张弃牌,第二张闲1，第三张庄1，第四张闲2，第五张庄2，第六张补牌(闲符合博牌规则时闲3，否则看庄符合博牌规则时庄3，再否则还回牌靴)，第七张补牌(当第六张牌补给闲时，看庄符合博牌规则时庄3，否则还回牌靴);
4.靴尾，当牌靴剩下的牌不足7张时，该局结束，剩下的牌为靴尾
]]

local random = math.random
local table_copy = table.copy

local Rule = class("Rule")



function  Rule:ctor()
	--随机种子
	math.randomseed(os.time())
	--扑克牌说明，0xAB, (A为花色 0黑桃 1红心 2草花 3方块)，B为点数1-13为A-K 
	self.card = {
		0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d,
     	0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d,
     	0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2a, 0x2b, 0x2c, 0x2d,
     	0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a, 0x3b, 0x3c, 0x3d
	}

	self.wantCardTag = {
		PLAY_WIN = 1,	--闲赢
		BANK_WIN = 2,	--庄赢
		TIE = 3,		--和
	}
	--要发的牌
	self.tbCard = {}
	self.cardPairs = 8	--有几副牌
	self.headNum = 7	--靴头
	self.tailNum = 7	--靴尾,当少于7张时本局结束
		
end

--洗牌
function Rule:shuffle()	
	self.tbCard = {}
	for i = 1, self.cardPairs do 
		for _, v in pairs(self.card) do 
			table.insert(self.tbCard, v)
		end
	end	
	table.mix(self.tbCard)
	-- for i =1, 7 do --去掉靴头
	-- 	table.remove(self.tbCard, 1)
	-- end

end

--取靴头牌
function Rule:getHeadCard()
	local tbRes = {}
	for k=1, self.headNum do
		tbRes[k] = table.remove(self.tbCard, 1)		
	end
	return tbRes
end

--取靴尾数
function Rule:geTailNum()
	return self.tailNum
end

--取闲，庄牌
function Rule:getPlayAndBankCards()	
	local playCards = {} --闲牌
	local bankCards = {} --庄牌
	if #self.tbCard < self.tailNum then
		return playCards, bankCards
	end
	--闲庄先各发两张牌
	for k=1, 4 do
		if k == 1 or k == 3 then
			table.insert(playCards, table.remove(self.tbCard, 1))			
		elseif k == 2 or k == 4 then
			table.insert(bankCards, table.remove(self.tbCard, 1))
		end	
	end
	local playPoint = self:getPoint(playCards)
	local bankPoint = self:getPoint(bankCards)
	if playPoint == 8 or playPoint == 9 or
	   bankPoint == 8 or bankPoint == 9 then --8， 9点都不博牌
		return playCards, bankCards
	end

	--闲	
	if playPoint <= 5 then
		table.insert(playCards, table.remove(self.tbCard, 1))
		playPoint = self:getPoint(playCards)
	end

	--庄
	local bankPoint = self:getPoint(bankCards)
	if bankPoint < 3 then
		table.insert(bankCards, table.remove(self.tbCard, 1))
		return playCards, bankCards 
	elseif bankPoint == 3 then
		if #playCards == 3 and playPoint == 8 then
			return playCards, bankCards 
		else
			table.insert(bankCards, table.remove(self.tbCard, 1))
			return playCards, bankCards 
		end
	elseif bankPoint == 4 then
		if #playCards == 3 and (playPoint == 1 or playPoint == 8 or playPoint == 9 or playPoint == 0) then
			return playCards, bankCards 
		else
			table.insert(bankCards, table.remove(self.tbCard, 1))
			return playCards, bankCards 
		end
	elseif bankPoint == 5 then
		if #playCards == 3 and (playPoint == 1 or playPoint == 8 or playPoint == 9 or playPoint == 0) then
			return playCards, bankCards 
		else
			table.insert(bankCards, table.remove(self.tbCard, 1))
			return playCards, bankCards 
		end
	elseif bankPoint == 6 then
		if #playCards == 3 and (playPoint == 6 or playPoint == 7) then
			table.insert(bankCards, table.remove(self.tbCard, 1))
			return playCards, bankCards 			
		else
			return playCards, bankCards 
		end
	elseif bankPoint == 7 then
		return playCards, bankCards 
	end

	print("-------->取牌出错：", "playCards:", playCards, "bankCards:", bankCards)
	return playCards, bankCards
end

--把牌添加到牌屑
function Rule:addToCardCase(card)	
	local function _existInRuleCard(cardValue)		
		for k, v in pairs(self.card) do
			if v == cardValue then
				return true
			end
		end
		return false
	end  

	if type(card) == "table" then
		for _, v in pairs(card) do
			if _existInRuleCard(v) then
				table.insert(self.tbCard, v)
			end				
		end 		
	elseif type(card) == "number" then
		if _existInRuleCard(card) then
			table.insert(self.tbCard, card)
		end	
	end
end

--每轮开始取一张弃牌
function Rule:getFoldCard()
	return table.remove(self.tbCard, 1)
end

--取本局剩余牌数
function Rule:getLeftCardCount()
	return #self.tbCard
end

--取剩余牌
function Rule:getLeftCard()
	return table_copy(self.tbCard)
end

--清空牌
function Rule:clearCard()
	self.tbCard = {}
end

--取剩余每张牌的数量
function Rule:getEachCardLeftNum()
	local tb = {}
	for _, u in ipairs(self.card) do
		tb[u] = 0
	end

	for k, v in pairs(self.tbCard) do
		tb[v] = (tb[v] or 0) + 1
	end
	return tb
end

--是否有对子 
function Rule:existPair(tbCard)
	if #tbCard < 2 then 
		return false
	end

	for k, v in ipairs(tbCard) do
		for j = k + 1, #tbCard do
			if tbCard[k] & 0x0f == tbCard[j] & 0x0f then
				return true
			end
		end
	end
	return false
end

--获取点数
function Rule:getPoint(tbCard)
	local point = 0
	for k, v in ipairs(tbCard) do
		local temp = (v & 0x0f)
		if temp < 10 then
			point = temp + point
		end		
	end
	point = point % 10
	return point
end

--比牌， res1大于res2：1，小于-1，和：0
function Rule:compareCard(tbRes1, tbRes2)
	local point1 = self:getPoint(tbRes1)
	local point2 = self:getPoint(tbRes2)
	if point1 > point2 then
		return 1
	elseif point1 < point2 then
		return -1
	else
		return 0
	end
end
--[[
wantCardTag:闲赢:Rule.wantCardTag.PLAY_WIN; 庄赢: Rule.wantCardTag.BANK_WIN,和:Rule.wantCardTag.TIE；
noPlayPair：为true时闲不出现对子；
noBankPair：为true时庄不出现对子；
]]--
function Rule:getWantCard(wantCardTag, noPlayPair, noBankPair)
	local play, bank = {}, {}
	if not wantCardTag and not noPlayPair and not noBankPair then
		return self:getPlayAndBankCards()
	end

	local tryNum = 100
	if #self.tbCard > 100 then
		tryNum = 500
	end
	if wantCardTag == self.wantCardTag.TIE or noPlayPair == true or noBankPair == true then
		tryNum = tryNum + 200
	end

	for n = 1, tryNum do
		local playCard, bankCard = self:getPlayAndBankCards()
		local compareRes = self:compareCard(playCard, bankCard)
		local isPlayPair = self:existPair(playCard)
		local isBankPair = self:existPair(bankCard)

		if (not noPlayPair and not noBankPair) or
			(noPlayPair and not isPlayPair and noBankPair and not isBankPair) or
		    (noPlayPair and not isPlayPair and  not noBankPair) or 
			(noBankPair and not isBankPair and not isPlayPair) then
			play, bank = playCard, bankCard --符合对子条件的
			if wantCardTag == self.wantCardTag.PLAY_WIN and compareRes == 1 then
				return playCard, bankCard
			elseif wantCardTag == self.wantCardTag.BANK_WIN and compareRes == -1 then				
				return playCard, bankCard
			elseif wantCardTag == self.wantCardTag.TIE and compareRes == 0 then
				return playCard, bankCard
			end			
		end
		for _,v in ipairs(bankCard) do
			table.insert(self.tbCard, v)
		end
		for _,v in ipairs(playCard) do
			table.insert(self.tbCard, v)
		end
		table.mix(self.tbCard)
	end

	for _, v in pairs(play) do
		for i, u in ipairs(self.tbCard) do
			if v == u then
				table.remove(self.tbCard, i)
			end
		end		
	end

	for _, v in pairs(bank) do
		for i, u in ipairs(self.tbCard) do
			if v == u then
				table.remove(self.tbCard, i)
			end
		end		
	end

	--如果没找到符合条件的
	if table.empty(play) or table.empty(bank) then
		print("not find........")
		play, bank = self:getPlayAndBankCards()
	end	
	return play, bank, true
end

return Rule